package test1;

import service.Service;
import extthread.ThreadA;
import extthread.ThreadB;

/**
 * 将任意对象作为对象监视器
 * 多个线程调用同一个对象中的不同名称的synchronized 同步方法或synchronized(this)
 * 同步代码块时，调用的效果就是按顺序执行，也就是同步的，阻塞的。
 * 这说明synchronized同步方法或synchronized(this)同步代码块分别有两种作用。
 * (1)synchronized同步方法
 * 1)对其他synchronized同步方法或synchronized(this)同步代码块调用呈阻塞状态
 * 2)同一时间只有一个线程可以执行synchronized同步方法中的代码。
 * (2)synchronized(this)同步代码块
 * 1)对其他synchronized同步方法或synchronized(this)同步代码块调用呈阻塞状态。
 * 2)同一时间只有一个线程可以执行synchronized(this)同步代码块中的代码。
 *
 * 在签名的学习中，使用synchronized(this)格式来同步代码块，其实Java还支持对“任意对象”
 * 作为“对象监视器”来实现同步的功能。这个“任意对象”大多数是实例变量及方法的参数，
 * 使用格式为synchronized(非this对象)
 *
 * 根据前面对synchronized(this)同步代码块的作用总结可知，synchronized(非this对象)
 * 格式的作用只有1中：synchronized(非this对象x)同步代码块。
 * 1)在多个线程持有“对象监视器”为同一个对象的前提下，同一时间只有一个线程可以执行synchronized
 * (非this对象x)同步代码块中的代码。
 * 2)当持有“对象监视器”为同一个对象的前提下，同一时间只有一个线程可以执行synchronized(非this对象x)
 * 同步代码块中的代码。
 *
 */

/**
 * 以下示例验证第一点
 */
public class Run {

	public static void main(String[] args) {
		Service service = new Service();

		ThreadA a = new ThreadA(service);
		a.setName("A");
		a.start();

		ThreadB b = new ThreadB(service);
		b.setName("B");
		b.start();

	}

	/**
	 * private String anyString = new String();
	 * 输出结果：
	 * 线程名称为：A在1529637490171进入同步块
	   线程名称为A在1529637493172离开同步块
	   线程名称为：B在1529637493172进入同步块
	   线程名称为B在1529637496172离开同步块
	 *
	 * 锁非this对象具有一定的优点：如果在一个类中有很多个synchronized方法，这时虽然能实现同步，但会
	 * 受到阻塞，所以影响运行效率；但如果使用同步代码块锁非this对象，则synchronized(非this)代码块
	 * 中的程序与同步方法是异步的，不与其他锁this同步方法争抢this锁，则可大大提高运行效率。
	 *
	 *
	 * 注释private String anyString = new String();
	 * 方法内添加String anyString = new String();
	 * 输出结果：
	 * 线程名称为：A在1529645676874进入同步块
	   线程名称为：B在1529645676875进入同步块
	   线程名称为A在1529645679874离开同步块
	   线程名称为B在1529645679875离开同步块
	 *
	 * 使用“synchronized(非this对象x)同步代码块”格式进行同步操作时，对象监视器必须是
	 * 同一个对象。如果不是同一个对象监视器，运行的结果就是异步调用了，就会交叉运行。
	 */

}
